<?php
/**
 * Department.php
 * 部门接口
 * @author Deepseath
 * @version $Id$
 */
namespace deepseath\xinrenxinshi\Api;

use deepseath\xinrenxinshi\Xinrenxinshi;

class Department
{
    /**
     * 基类服务对象
     * @var \deepseath\xinrenxinshi\Xinrenxinshi
     */
    protected $service = null;

    /**
     * 是否包含子部门：包含
     * @var integer
     */
    const INCLUDE_CHILDREN_YES = 1;
    /**
     * 是否包含子部门：不包含
     * @var integer
     */
    const INCLUDE_CHILDREN_NO = 0;

    /**
     * 部门状态：正常
     * @var integer
     */
    const STATUS_NORMAL = 0;
    /**
     * 部门状态：禁用
     * @var integer
     */
    const STATUS_DISABLE = 1;
    /**
     * 部门状态：删除
     * @var integer
     */
    const STATUS_DELETED = 2;

    private $jobDetailList = [];

    public function __construct(Xinrenxinshi $service)
    {
        $this->service = $service;
    }

    /**
     * 1.6.2 部门列表
     * @desc 查询公司部门信息，不包含虚拟部门信息
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/list_v5.html
     * @param array $params
     * @return array
     */
    public function ls(array $params = []) : array
    {
        $params = array_merge([
            // string	N	部门ID
            'departmentId' => '',
            // Integer	N	是否获取子部门，默认0，0-不包含、1-包含
            'fetchChild' => self::INCLUDE_CHILDREN_YES,
            // Integer	N	部门状态，默认为0，0-正常、1-禁用
            'status' => self::STATUS_NORMAL,
            // Integer	N	更新时间(精确到秒)，部门列表的增量查询。如果传了该参数，则只返回更新时间在查询时间之后的部门数据
            'modtime' => 0,
        ], $params);
        return $this->service->apiPost('/department/list', $params);
    }

    /**
     * 1.6.5 获取部门类型
     * @desc 获取系统中的部门类型列表。
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/dept_type_v5.html
     * @param array $params
     * @return array
     */
    public function depTypeList(array $params = []) : array
    {
        $params = array_merge([], $params);
        return $this->service->apiPost('/department/depttype/list', $params);
    }

    /**
     * 1.6.6 获取岗位信息
     * @desc 获取公司全部的岗位信息。包含岗位id，岗位名称以及岗位编码。
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/postInfo_v5.html
     * @param array $params
     * <pre>
     *  departmentId	String	N	部门id，不传时，默认返回公司所有的岗位详细信息，有值时返回指定部门下的岗位列表
     * </pre>
     * @return array
     */
    public function jobList(array $params = []) : array
    {
        $params = array_merge([
            // String	N	部门id，不传时，默认返回公司所有的岗位详细信息，有值时返回指定部门下的岗位列表
            'departmentId' => ''
        ], $params);

        return $this->service->apiPost('/department/jobdictionary/list', $params);
    }

    /**
     * 1.6.7 获取岗位详细信息
     * @desc 获取公司岗位词典的详细信息。包含岗位id，父岗位id，岗位分类，岗位名称，岗位编码，岗位说明以及岗位备注以及适用部门。
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/jobdictionary_v5.html
     * @param array $params
     * <pre>
     *   jobId 和 departmentId 都为空时，获取公司全部的岗位详细信息
     *   jobId不为空，获取公司单个指定岗位详细信息
     *   jobId为空且departmentId不为空时，获取公司指定部门下的岗位信息
     * </pre>
     * @return array
     */
    public function jobDetailList(array $params = []) : array
    {
        if (empty($params['departmentId']) && !empty($this->jobDetailList)) {
            return $this->jobDetailList;
        }
        $params = array_merge([
            // String	N	岗位id，传值时，返回指定岗位的详细信息
            'jobId' => '',
            // String	N	部门id，传值时，返回公司对应部门下的岗位详细信息
            'departmentId' => ''
        ], $params);

        $result = $this->service->apiPost('/department/jobdictionary/detaillist', $params);
        if (empty($params['departmentId'])) {
            $this->jobDetailList = $result;
        }
        return $result;
    }

    /**
     * 1.6.8 获取成本中心信息
     * @desc 获取公司的成本中心信息，包含成本中心id，父成本中心id，成本中心名称以及成本中心编码
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/costList_v5.html
     * @param array $params
     * <pre>
     *   costId为空时，获取公司所有成本中心信息
     *   costId不为空时，获取公司单个指定成本中心信息
     * </pre>
     * @return array
     */
    public function costcenterList(array $params) : array
    {
        $params = array_merge([], $params);

        return $this->service->apiPost('/department/costcenter/list', $params);
    }

    /**
     * 1.6.9 获取职级信息
     * @desc 获取公司全部的职级信息。包含职级id，职级名称，职务，等级id，等级编码等信息
     * @see https://api.xinrenxinshi.com/doc/v3/page/department/rank_v5.html
     * @param array $params
     * @return array
     */
    public function rankList(array $params = []) : array
    {
        $params = array_merge([], $params);
        return $this->service->apiPost('/department/rank/list', $params);
    }

    /**
     * 1.6.2.1 获取带层级关系的全部正常部门列表
     * @param array $result
     * @param string $parentId
     */
    public function ddListLevels(array &$result, string $parentId = '')
    {
        static $list = null;
        if ($list === null) {
            $list = $this->ls();
        }
        foreach ($list as $dp) {
            if ($dp['parentId'] === $parentId) {
                $tmp = $dp;
                $tmp['childrenList'] = [];
                $this->ddListLevels($tmp['childrenList'], $dp['departmentId']);
                $result[$dp['departmentId']] = $tmp;
                unset($tmp);
            }
        }
    }

    /**
     * 1.6.2.2 获取指定部门的全部父级部门
     * @param array $result         引用返回结果，由最下级部门到最顶级部门排序
     * @param string $departmentId  指定部门的 id
     */
    public function ddParents(array &$result, string $departmentId)
    {
        static $list = null;
        if ($list === null) {
            $list = $this->ls();
        }

        foreach ($list as $dp) {
            if ($dp['departmentId'] == $departmentId) {
                $result[] = $dp;
                if ($dp['parentId'] !== '') {
                    $this->ddParents($result, $dp['parentId']);
                }
            }
        }
    }

    /**
     * 找到指定部门的关键字段值，如果当前部门该值为空则递归寻找父级部门直至不为空
     * @desc 例如，可以获取指定部门的直接负责人（key: adminId）、hrbpId（key：hrbpId）
     * @param string $departmentId
     * @param string $key
     * @return string
     */
    public function ddDpKey(string $departmentId, string $key = 'adminId') : string
    {
        static $list = null;
        if ($list === null) {
            $list = $this->ls();
            $list = array_combine(array_column($list, 'departmentId'), $list);
        }
        if (isset($list[$departmentId])) {
            if ($list[$departmentId][$key] !== '') {
                return $list[$departmentId][$key];
            } elseif ($list[$departmentId]['parentId'] !== '') {
                return $this->ddDpKey($list[$departmentId]['parentId'], $key);
            } else {
                return '';
            }
        } else {
            return '';
        }
    }

    /**
     * 1.6.2.3 部门 ID 与部门负责人 ID 对应关系 key-value
     * @return array
     */
    public function ddDpMsters()
    {
        static $list = null;
        if ($list === null) {
            $list = $this->ls();
        }
        $result = array_combine(array_column($list, 'departmentId'), array_column($list, 'adminId'));
        foreach ($result as $departmentId => &$employeeId) {
            if ($employeeId === '') {
                $employeeId = $this->ddDpKey($departmentId, 'adminId');
            }
        }

        return $result;
    }
}
